1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.base;
18
19 import com.google.caliper.BeforeExperiment;
20 import com.google.caliper.Benchmark;
21 import com.google.caliper.Param;
22 import com.google.caliper.runner.CaliperMain;
23 import com.google.common.base.CharMatcher.FastMatcher;
24
25 import java.util.BitSet;
26 import java.util.Random;
27
28
29
30
31 public class WhitespaceMatcherBenchmark {
32 private static final int STRING_LENGTH = 10000;
33
34 private static final String OLD_WHITESPACE_TABLE =
35 "\u0001\u0000\u00a0\u0000\u0000\u0000\u0000\u0000"
36 + "\u0000\u0009\n\u000b\u000c\r\u0000\u0000\u2028\u2029\u0000\u0000\u0000\u0000\u0000\u202f"
37 + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0020\u0000\u0000\u0000\u0000\u0000"
38 + "\u0000\u0000\u0000\u0000\u0000\u3000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
39 + "\u0000\u0000\u0085\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a"
40 + "\u0000\u0000\u0000\u0000\u0000\u205f\u1680\u0000\u0000\u180e\u0000\u0000\u0000";
41
42 public static final CharMatcher OLD_WHITESPACE = new FastMatcher("CharMatcher.WHITESPACE") {
43 @Override public boolean matches(char c) {
44 return OLD_WHITESPACE_TABLE.charAt(c % 79) == c;
45 }
46 };
47
48 @Param
49 private boolean useNew;
50
51 @Param({"20", "50", "80"})
52 private int percentMatching;
53
54 private String teststring;
55 private CharMatcher matcher;
56
57 public static void main(String[] args) throws Exception {
58 CaliperMain.main(WhitespaceMatcherBenchmark.class, new String[] {});
59 }
60
61 @BeforeExperiment
62 protected void setUp() {
63 BitSet bitSet = new BitSet();
64 for (int i = 0; i < OLD_WHITESPACE_TABLE.length(); i++) {
65 bitSet.set(OLD_WHITESPACE_TABLE.charAt(i));
66 }
67 bitSet.clear(0);
68 bitSet.clear(1);
69 matcher = useNew ? CharMatcher.WHITESPACE : OLD_WHITESPACE;
70 teststring = newTestString(new Random(1), bitSet, percentMatching);
71 }
72
73 @Benchmark public int countIn(int reps) {
74 int result = 0;
75 CharMatcher matcher = this.matcher;
76 String teststring = this.teststring;
77 for (int i = 0; i < reps; i++) {
78 result += matcher.countIn(teststring);
79 }
80 return result;
81 }
82
83 @Benchmark public int collapseFrom(int reps) {
84 int result = 0;
85 CharMatcher matcher = this.matcher;
86 String teststring = this.teststring;
87 for (int i = 0; i < reps; i++) {
88 result += System.identityHashCode(matcher.collapseFrom(teststring, ' '));
89 }
90 return result;
91 }
92
93 private static String allMatchingChars(BitSet bitSet) {
94 final char[] result = new char[bitSet.cardinality()];
95 for (int j = 0, c = bitSet.nextSetBit(0); j < result.length; ++j) {
96 result[j] = (char) c;
97 c = bitSet.nextSetBit(c + 1);
98 }
99 return new String(result);
100 }
101
102 private static String newTestString(Random random, BitSet bitSet, int percentMatching) {
103 final String allMatchingChars = allMatchingChars(bitSet);
104 final char[] result = new char[STRING_LENGTH];
105
106 for (int i = 0; i < result.length; i++) {
107 result[i] = allMatchingChars.charAt(random.nextInt(allMatchingChars.length()));
108 }
109
110 int remaining = (int) ((100 - percentMatching) * result.length / 100.0 + 0.5);
111 while (remaining > 0) {
112 final char c = (char) random.nextInt();
113 if (bitSet.get(c)) {
114 final int pos = random.nextInt(result.length);
115 if (bitSet.get(result[pos])) {
116 result[pos] = c;
117 remaining--;
118 }
119 }
120 }
121 return new String(result);
122 }
123 }